package com.biglead.demo.service.impl;

import com.biglead.demo.common.R;
import com.biglead.demo.mapper.OrderMapper;
import com.biglead.demo.pojo.*;
import com.biglead.demo.rabbit.OrderMQSender;
import com.biglead.demo.service.GoodsService;
import com.biglead.demo.service.OrderService;
import com.biglead.demo.service.SecKillGoodsService;
import com.biglead.demo.service.SecKillOrderService;
import com.biglead.demo.utils.JsonUtils;
import com.biglead.demo.vo.GoodsVo;
import com.biglead.demo.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService , InitializingBean {
    @Autowired
    private SecKillGoodsService secKillGoodsService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SecKillOrderService secKillOrderService;
    @Override
    @Transactional // 一个事务
    public R toSecKill(Long goodsId, Long userId) {
        // 秒杀商品表库存减一
        SeckillGoods seckillGoods = secKillGoodsService.findByGoodsId(goodsId);
        seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);
        // 库存超卖
        int update = secKillGoodsService.updateStockCount(seckillGoods);
        if (update < 1) {
            log.error("商品库存更新失败 商品库存不足");
            // 更新失败
            return R.error("商品库存不足");
        }
        Goods goods = goodsService.findGoods(goodsId);

        if (seckillGoods.getStockCount() < 1) {
            // 设置该商品库存为空
            redisTemplate.opsForValue().set("isStockEmpty:" + goods.getId(), "0");

            return R.error("商品库存不足");
        }



        // 下订单
        Order order = new Order();
        order.setUserId(userId);
        order.setGoodsId(goodsId);
        order.setDeliveryAddrId(0L);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsCount(1);
        order.setGoodsPrice(seckillGoods.getSeckillPrice());
        order.setOrderChannel(1);
        order.setStatus(0); // 订单创建中
        order.setCreateDate(new Date());
        orderMapper.insert(order);

        // 生成秒杀订单
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder.setUserId(userId);
        seckillOrder.setOrderId(order.getId());
        seckillOrder.setGoodsId(goods.getId());
        secKillOrderService.save(seckillOrder);

        //缓存秒杀订单
        redisTemplate.opsForValue().set("order:" +userId + ":" + goodsId, seckillOrder);

        return R.okData(order);
    }

    @Override
    public OrderVo detail(Long orderId) {
        if(orderId==null){
            throw new RuntimeException("订单不存在");
        }
        Order order = orderMapper.selectById(orderId);
        if ( Objects.isNull(order)) {
            // 订单不存在
            throw new RuntimeException("订单不存在");
        }
        GoodsVo goodsVo = goodsService.findGoodsVoByGoodsId(order.getGoodsId());

        OrderVo orderVo = new OrderVo();
        orderVo.setOrder(order);
        orderVo.setGoodsVo(goodsVo);
        return orderVo;
    }


    @Autowired
    private OrderMQSender mqSender;
    @Override
    public R createPreOrder(Long goodsId, Long userId) {
        log.info("预下单处理 userId:{} goodsId:{} ",userId,goodsId);

        //获取redis中的商品库存 先判断商品是否有库存
        Boolean aBoolean = redisTemplate.hasKey("goodStock:" + goodsId);
        if(Boolean.FALSE.equals(aBoolean)){
           return R.error("下单失败 商品库存不足");
        }
        //获取商品库存
        int goodsStock = Integer.valueOf(redisTemplate.opsForValue().get("goodStock:" +goodsId).toString());
        if(goodsStock==0){
            return R.error("下单失败 商品库存不足");
        }
        //发送下单消息
        SecKillMessage message = new SecKillMessage(userId, goodsId);
        mqSender.sendCommonOrderMessage(JsonUtils.toJson(message));
        return R.okData("预下单成功");
    }

    @Override
    @Transactional
    public R createOrder(Long goodsId, Long userId) {

        log.info("下单处理 userId:{} goodsId:{} ",userId,goodsId);
       //查询商品详情
        Goods goods = goodsService.findGoods(goodsId);
        //商品的实际库存
        if (goods.getGoodsStock() < 1) {
            // 设置该商品库存为空
            redisTemplate.opsForValue().set("goodStock:" + goods.getId(), "0");
            log.info("库存不足 下单失败");
            return R.error("商品库存不足");
        }
        //减库存
        int currentStock = goods.getGoodsStock() -1;
        //更新数据库 库存
        goods.setGoodsStock(currentStock);
        int update = goodsService.updateGoodsStock(goods);
        if(update<=0){
            log.info("更新库存失败 下单失败");
            return R.error("商品库存不足");
        }
        //更新redis 缓存
        redisTemplate.opsForValue().set("goodStock:" + goods.getId(), currentStock);
        // 下订单
        Order order = new Order();
        order.setUserId(userId);
        order.setGoodsId(goodsId);
        order.setDeliveryAddrId(0L);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsCount(1);
        order.setGoodsPrice(goods.getGoodsPrice());
        order.setOrderChannel(1);
        order.setStatus(0); // 订单创建中
        order.setCreateDate(new Date());
        orderMapper.insert(order);
        log.info("下单成功 userId:{} goodsId:{} orderId:{}",userId,goodsId,order.getId());
        //缓存普通订单
        redisTemplate.opsForValue().set("order:" +userId + ":" + goodsId, order);
        //保存数据到ES中
        //后续实现
        return R.okData(order);
    }

    /**
     * 初始化秒杀商品数量到 redis 中
     *
     * @return
     */
    @Override
    public R startSeckillInit() {
        List<SeckillGoods> goods = secKillGoodsService.findAllSecKillGoods();
        if (CollectionUtils.isEmpty(goods)) {
            return R.error("无秒杀商品");
        }

        goods.forEach(g -> {
            log.info("初始化秒杀商品 goodsId:{} stock: {}", g.getGoodsId(), g.getStockCount());
            redisTemplate.opsForValue().set("goodStock:" + g.getGoodsId(), g.getStockCount());
        });
        return R.ok("初始化完成");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.startSeckillInit();
    }
}
